package com.server.config.security;

import com.server.pojo.Admin;
import com.server.service.IAdminService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.provisioning.InMemoryUserDetailsManager;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;


/**
 * @ClassName: SecurityConfig
 * @Description: 安全框架的配置类
 * @Author: SongHL
 * @Date: 2025/9/13
 */
@Configuration
@EnableWebSecurity
public class SecurityConfig{

    @Autowired
    private IAdminService adminService;

    //注入自定义的错误返回
    //未登录
    @Autowired
    private RestAuthorizationEntryPoint restAuthorizationEntryPoint;

    //权限不足
    @Autowired
    private RestfulAccessDeniedHandler restfulAccessDeniedHandler;

    // 配置安全过滤链（替代原有的 configure(HttpSecurity http) 方法）
    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        //使用JWT，不需要csrf
        http.csrf(csrf -> csrf.disable())
                //基于token，不要session
                .sessionManagement(
                        session -> session
                                .sessionCreationPolicy(SessionCreationPolicy.STATELESS)
                )
                // 授权配置
                .authorizeHttpRequests(auth -> auth
                        // 允许登录和登出接口匿名访问
                        .requestMatchers("/login", "/logout").permitAll()
                        // 其他所有请求需要认证
                        .anyRequest().authenticated()
                )
                // 禁用缓存
                .headers(headers -> headers
                        .cacheControl(cache -> cache.disable())
                )
                // 添加 JWT 过滤器（在用户名密码认证过滤器之前）
                .addFilterBefore(jwtAuthenticationTokenFilter(), UsernamePasswordAuthenticationFilter.class)
                // 异常处理配置
                .exceptionHandling(ex -> ex
                        // 处理未授权访问
                        .accessDeniedHandler(restfulAccessDeniedHandler)
                        // 处理未登录访问
                        .authenticationEntryPoint(restAuthorizationEntryPoint)
                );

        // 必须返回构建好的 SecurityFilterChain 对象
        return http.build();
    }

    // 配置用户信息（替代原有的 configure(AuthenticationManagerBuilder auth) 方法）
    // 通过 lambda 直接提供了接口实现（本质上还是实现类，只是形式更简洁）。
    @Bean
    public UserDetailsService userDetailsService() {
       return username -> {
           Admin admin = adminService.getAdminByUsername(username);
           if(admin != null){
               return admin;
           }
           return null;
       };
    }

    // 配置密码加密器
    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }

    @Bean
    public JwtAuthenticationTokenFilter jwtAuthenticationTokenFilter(){
        return new JwtAuthenticationTokenFilter();
    }
}
